import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import ttkbootstrap as ttk_bs
from ttkbootstrap.constants import *
from typing import Callable, Optional, Any, List, Dict
from utils.logger import get_logger


class CustomComponents:
    """自定义组件类"""
    
    def __init__(self):
        self.logger = get_logger("CustomComponents")


class ProjectSelector(ttk.Frame):
    """项目选择器组件"""
    
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.logger = get_logger("ProjectSelector")
        self.projects = []
        self.selected_projects = []  # 选中的项目路径列表
        self.callbacks = {}
        self.gitee_api = None  # 用于检查重名
        self.setup_ui()
    
    def setup_ui(self):
        """设置UI"""
        # 主框架
        main_frame = ttk.Frame(self)
        main_frame.pack(fill=BOTH, expand=True, padx=5, pady=5)
        
        
        # 按钮框架
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=X, pady=(0, 10))
        
        # 添加项目按钮
        self.add_btn = ttk_bs.Button(
            button_frame, 
            text="添加项目", 
            bootstyle=SUCCESS,
            command=self.add_project
        )
        self.add_btn.pack(side=LEFT, padx=(0, 5))
        
        # 添加多个项目按钮
        self.add_multiple_btn = ttk_bs.Button(
            button_frame, 
            text="批量添加", 
            bootstyle=INFO,
            command=self.add_multiple_projects
        )
        self.add_multiple_btn.pack(side=LEFT, padx=(0, 5))
        
        # 全选/取消全选
        self.select_all_btn = ttk_bs.Button(
            button_frame,
            text="全选",
            bootstyle=SECONDARY,
            command=self.toggle_select_all,
            width=10
        )
        self.select_all_btn.pack(side=LEFT, padx=(0, 5))
        
        # 清除选择按钮
        clear_selection_btn = ttk_bs.Button(
            button_frame,
            text="清除选择",
            bootstyle=LIGHT,
            command=self.clear_selection,
            width=10
        )
        clear_selection_btn.pack(side=LEFT, padx=(0, 5))
        
        # 批量删除选中
        batch_delete_btn = ttk_bs.Button(
            button_frame,
            text="删除选中",
            bootstyle=WARNING,
            command=self.delete_selected_projects,
            width=10
        )
        batch_delete_btn.pack(side=LEFT, padx=(0, 5))
        
        
        
        # 清空按钮
        self.clear_btn = ttk_bs.Button(
            button_frame, 
            text="清空列表", 
            bootstyle=DANGER,
            command=self.clear_projects
        )
        self.clear_btn.pack(side=LEFT, padx=(0, 5))
        
        # 批量智能名称按钮
        self.smart_name_btn = ttk_bs.Button(
            button_frame,
            text="🤖 批量智能名称",
            bootstyle=SUCCESS,
            command=self.generate_smart_names,
            width=18
        )
        self.smart_name_btn.pack(side=LEFT, padx=(0, 5))
        
        # 检查重名按钮
        self.check_duplicate_btn = ttk_bs.Button(
            button_frame,
            text="⚠️ 检查重名",
            bootstyle=WARNING,
            command=self.check_duplicate_names,
            width=15
        )
        self.check_duplicate_btn.pack(side=LEFT, padx=(0, 5))
        
        # 选择状态标签
        self.selection_label = ttk.Label(button_frame, text="已选择: 0 个")
        self.selection_label.pack(side=RIGHT, padx=10)
        
        # 项目列表框架
        list_frame = ttk.Frame(main_frame)
        list_frame.pack(fill=BOTH, expand=True)
        
        # 创建Treeview
        columns = ('select', 'project_name', 'project_path', 'status')
        self.tree = ttk.Treeview(list_frame, columns=columns, show='headings', height=10)
        
        # 设置列标题
        self.tree.heading('select', text='选择')
        self.tree.heading('project_name', text='项目名称')
        self.tree.heading('project_path', text='项目路径') 
        self.tree.heading('status', text='状态')
        
        # 设置列宽
        self.tree.column('select', width=60, anchor='center')
        self.tree.column('project_name', width=150)
        self.tree.column('project_path', width=300)
        self.tree.column('status', width=100)
        
        # 滚动条
        scrollbar = ttk.Scrollbar(list_frame, orient=VERTICAL, command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)
        
        # 布局
        self.tree.pack(side=LEFT, fill=BOTH, expand=True)
        scrollbar.pack(side=RIGHT, fill=Y)
        
        # 右键菜单
        self.context_menu = tk.Menu(self, tearoff=0)
        self.context_menu.add_command(label="编辑项目", command=self.edit_selected_project)
        self.context_menu.add_command(label="手动修改名称", command=self.manual_rename_single_project)
        self.context_menu.add_separator()
        self.context_menu.add_command(label="删除项目", command=self.remove_selected_project)
        
        # 绑定事件
        self.tree.bind("<Button-1>", self.on_tree_click)
        self.tree.bind("<Button-3>", self.show_context_menu)
        self.tree.bind("<Double-1>", self.edit_selected_project)
    
    def add_project(self):
        """添加单个项目"""
        project_path = filedialog.askdirectory(title="选择项目目录")
        if project_path:
            self._add_project_to_list(project_path)
    
    def add_multiple_projects(self):
        """批量添加项目"""
        parent_dir = filedialog.askdirectory(title="选择包含多个项目的父目录")
        if parent_dir:
            import os
            try:
                for item in os.listdir(parent_dir):
                    item_path = os.path.join(parent_dir, item)
                    if os.path.isdir(item_path):
                        self._add_project_to_list(item_path)
            except Exception as e:
                messagebox.showerror("错误", f"批量添加项目失败: {str(e)}")
    
    def _add_project_to_list(self, project_path: str):
        """添加项目到列表"""
        import os
        project_name = os.path.basename(project_path)
        
        # 检查是否已存在
        for project in self.projects:
            if project['path'] == project_path:
                messagebox.showwarning("警告", f"项目已存在: {project_name}")
                return
        
        # 添加到列表
        project_data = {
            'name': project_name,
            'path': project_path,
            'status': '待处理'
        }
        self.projects.append(project_data)
        
        # 添加到树视图（默认未选中）
        self.tree.insert('', END, values=('☐', project_name, project_path, '待处理'))
        
        # 触发回调
        self._trigger_callback('on_project_added', project_data)
        
        # 更新选择计数显示
        self._update_selection_count()
    
    def remove_selected_project(self):
        """删除选中的项目"""
        selected_item = self.tree.selection()
        if not selected_item:
            messagebox.showwarning("警告", "请先选择要删除的项目")
            return
        
        # 获取项目信息
        item = self.tree.item(selected_item[0])
        project_path = item['values'][2]  # 路径现在在第3列
        
        # 从列表中删除
        self.projects = [p for p in self.projects if p['path'] != project_path]
        
        # 从树视图删除
        self.tree.delete(selected_item[0])
        
        # 触发回调
        self._trigger_callback('on_project_removed', project_path)
        
        # 更新选择计数显示
        self._update_selection_count()
    
    def edit_selected_project(self, event=None):
        """编辑选中的项目"""
        selected_item = self.tree.selection()
        if not selected_item:
            return
        
        # 获取当前值
        item = self.tree.item(selected_item[0])
        current_values = item['values']
        
        # 创建编辑对话框
        dialog = ProjectEditDialog(self, current_values)
        if dialog.result:
            # 更新项目信息
            new_values = dialog.result
            # 保持选择状态，插入新的选择列
            updated_values = (current_values[0], new_values[0], new_values[1], new_values[2])
            self.tree.item(selected_item[0], values=updated_values)
            
            # 更新项目列表
            for project in self.projects:
                if project['path'] == current_values[2]:  # 路径现在在第3列
                    project['name'] = new_values[0]  # 名称在第1列（dialog返回的）
                    project['path'] = new_values[1]  # 路径在第2列（dialog返回的）
                    break
    
    def clear_projects(self):
        """清空项目列表"""
        if messagebox.askyesno("确认", "确定要清空所有项目吗？"):
            self.projects.clear()
            self.selected_projects.clear()  # 清空选择状态
            for item in self.tree.get_children():
                self.tree.delete(item)
            # 更新选择计数
            self._update_selection_count()
            self._trigger_callback('on_projects_cleared')
    
    def show_context_menu(self, event):
        """显示右键菜单"""
        # 选中右键点击的项
        item = self.tree.identify_row(event.y)
        if item:
            self.tree.selection_set(item)
            self.context_menu.post(event.x_root, event.y_root)
    
    def update_project_status(self, project_path: str, status: str):
        """更新项目状态"""
        for item in self.tree.get_children():
            values = self.tree.item(item, 'values')
            if values[2] == project_path:  # 路径现在在第3列
                new_values = (values[0], values[1], values[2], status)  # 保持选择状态
                self.tree.item(item, values=new_values)
                break
        
        # 更新内部列表
        for project in self.projects:
            if project['path'] == project_path:
                project['status'] = status
                break
    
    def remove_project_by_path(self, project_path: str):
        """根据路径移除项目"""
        try:
            # 从树视图中删除
            for item in self.tree.get_children():
                values = self.tree.item(item, 'values')
                if values[2] == project_path:  # 路径现在在第3列
                    self.tree.delete(item)
                    break
                    
            # 从选中列表中移除
            if project_path in self.selected_projects:
                self.selected_projects.remove(project_path)
            
            # 从内部列表中删除
            self.projects = [p for p in self.projects if p['path'] != project_path]
            
            # 触发回调
            self._trigger_callback('on_project_removed', project_path)
            
        except Exception as e:
            self.logger.error(f"移除项目失败: {e}")
    
    def on_tree_click(self, event):
        """处理列表点击事件"""
        # 获取点击的行
        item = self.tree.identify_row(event.y)
        if not item:
            return
        
        # 获取点击的列
        column = self.tree.identify_column(event.x)
        
        # 如果点击的是选择列（第一列）
        if column == '#1':
            self.toggle_project_selection(item)
        else:
            # 点击其他列时选中该行（但不切换勾选状态）
            self.tree.selection_set(item)
    
    def toggle_project_selection(self, item):
        """切换项目选择状态"""
        values = list(self.tree.item(item, 'values'))
        project_path = values[2]
        
        if values[0] == '☐':  # 未选择
            values[0] = '☑'  # 选中
            if project_path not in self.selected_projects:
                self.selected_projects.append(project_path)
        else:  # 已选择
            values[0] = '☐'  # 取消选择
            if project_path in self.selected_projects:
                self.selected_projects.remove(project_path)
        
        self.tree.item(item, values=values)
        
        # 更新选择计数
        self._update_selection_count()
        
        self.logger.info(f"切换项目选择: {values[1]}, 当前选中: {len(self.selected_projects)} 个")
    
    def toggle_select_all(self):
        """全选/取消全选"""
        if len(self.selected_projects) == len(self.projects):
            # 当前全选，取消全选
            self.selected_projects.clear()
            self.select_all_btn.configure(text="全选")
            select_symbol = '☐'
        else:
            # 全选
            self.selected_projects.clear()
            for project in self.projects:
                project_path = project['path']
                if project_path not in self.selected_projects:
                    self.selected_projects.append(project_path)
            
            self.select_all_btn.configure(text="取消全选")
            select_symbol = '☑'
        
        # 更新显示
        for item in self.tree.get_children():
            values = list(self.tree.item(item, 'values'))
            values[0] = select_symbol
            self.tree.item(item, values=values)
        
        # 更新选择计数
        self._update_selection_count()
        
        self.logger.info(f"全选操作: {select_symbol == '☑'}, 当前选中: {len(self.selected_projects)} 个")
    
    def clear_selection(self):
        """清除所有选择"""
        self.selected_projects.clear()
        
        # 更新显示
        for item in self.tree.get_children():
            values = list(self.tree.item(item, 'values'))
            values[0] = '☐'
            self.tree.item(item, values=values)
        
        # 更新选择计数
        self._update_selection_count()
        
        self.logger.info("已清除所有项目选择")
    
    

    def delete_selected_projects(self):
        """批量删除选中的项目"""
        if not self.selected_projects:
            messagebox.showwarning("警告", "请先选择要删除的项目")
            return
        
        import os
        
        if not messagebox.askyesno("确认删除", 
                                  f"确定要删除选中的 {len(self.selected_projects)} 个项目吗？\n\n"
                                  f"将删除: {', '.join([os.path.basename(p) for p in self.selected_projects[:5]])}"
                                  f"{'...' if len(self.selected_projects) > 5 else ''}"):
            return
        
        # 记录删除的项目数量
        deleted_count = len(self.selected_projects)
        
        # 删除选中的项目
        for project_path in self.selected_projects.copy():
            # 从内部列表删除
            self.projects = [p for p in self.projects if p['path'] != project_path]
            
            # 从树视图删除
            for item in self.tree.get_children():
                values = self.tree.item(item, 'values')
                if values[2] == project_path:
                    self.tree.delete(item)
                    break
            
            # 触发回调
            self._trigger_callback('on_project_removed', project_path)
        
        # 清空选择列表
        self.selected_projects.clear()
        
        # 更新选择计数
        self._update_selection_count()
        
        messagebox.showinfo("完成", f"已成功删除 {deleted_count} 个项目")
        self.logger.info(f"批量删除项目完成，删除了 {deleted_count} 个项目")
    
    def _update_selection_count(self):
        """更新选择计数和按钮状态"""
        selected_count = len(self.selected_projects)
        total_count = len(self.projects)
        
        # 更新选择状态标签
        self.selection_label.configure(text=f"已选择: {selected_count} 个")
        
        # 更新全选按钮状态
        if selected_count == 0:
            self.select_all_btn.configure(text="全选")
        elif selected_count == total_count:
            self.select_all_btn.configure(text="取消全选")
        else:
            self.select_all_btn.configure(text=f"全选({selected_count}/{total_count})")
    
    def set_callback(self, event_name: str, callback: Callable):
        """设置回调函数"""
        self.callbacks[event_name] = callback
    
    def _trigger_callback(self, event_name: str, *args):
        """触发回调函数"""
        if event_name in self.callbacks:
            try:
                self.callbacks[event_name](*args)
            except Exception as e:
                self.logger.error(f"回调函数执行失败: {e}")
    
    def manual_rename_single_project(self):
        """手动修改单个项目名称"""
        selected_item = self.tree.selection()
        if not selected_item:
            messagebox.showwarning("警告", "请先选择要修改名称的项目")
            return
        
        # 获取项目信息
        item = self.tree.item(selected_item[0])
        project_path = item['values'][2]  # 路径现在在第3列
        
        # 找到对应的项目数据
        project_info = None
        for proj in self.projects:
            if proj['path'] == project_path:
                project_info = proj
                break
        
        if not project_info:
            messagebox.showerror("错误", "无法找到项目信息")
            return
        
        # 创建单个项目重命名对话框
        from gui.single_project_rename import SingleProjectRenameDialog
        dialog = SingleProjectRenameDialog(self, project_info)
        if dialog.result:
            new_name = dialog.result
            
            # 更新项目数据
            project_info['smart_name'] = new_name
            
            # 更新显示
            new_values = list(item['values'])
            new_values[1] = f"{project_info['name']} → {new_name}"
            self.tree.item(selected_item[0], values=new_values)
            
            messagebox.showinfo("完成", f"项目名称已修改为: {new_name}")
            self.logger.info(f"手动修改项目名称: {project_info['name']} -> {new_name}")
    
    def generate_smart_names(self):
        """为所有项目生成智能的仓库名称"""
        if not self.projects:
            messagebox.showwarning("警告", "项目列表为空")
            return
        
        # 确认操作
        if not messagebox.askyesno("确认", 
                                  f"是否为 {len(self.projects)} 个项目生成智能仓库名称？\n\n"
                                  "这将使用DeepSeek AI分析项目内容并生成更合适的英文名称。"):
            return
        
        try:
            # 显示进度对话框
            progress = ProgressDialog(self, "生成智能名称", "正在分析项目并生成名称...")
            
            # 导入DeepSeek AI
            from core.deepseek_ai import DeepSeekAI
            from core.config import config_manager
            
            # 获取DeepSeek API配置
            api_key = config_manager.get('ai.deepseek_api_key', '')
            deepseek = DeepSeekAI(api_key)
            
            success_count = 0
            total_count = len(self.projects)
            
            # 为每个项目生成智能名称
            for i, project in enumerate(self.projects):
                if progress.cancelled:
                    break
                
                project_name = project['name']
                project_path = project['path']
                
                # 更新进度
                progress_percent = (i / total_count) * 100
                progress.update_progress(
                    progress_percent,
                    f"正在处理: {project_name} ({i+1}/{total_count})"
                )
                
                try:
                    # 生成智能名称
                    smart_name = deepseek.generate_repository_name(project_name, project_path)
                    
                    # 更新项目信息
                    project['smart_name'] = smart_name
                    
                    # 更新树视图显示
                    for item in self.tree.get_children():
                        values = self.tree.item(item, 'values')
                        if values[2] == project_path:  # 匹配路径
                            # 更新显示的名称（在原名称后添加建议）
                            new_values = list(values)
                            new_values[1] = f"{project_name} → {smart_name}"
                            self.tree.item(item, values=new_values)
                            break
                    
                    success_count += 1
                    self.logger.info(f"生成智能名称: {project_name} -> {smart_name}")
                    
                except Exception as e:
                    self.logger.error(f"为项目 {project_name} 生成智能名称失败: {e}")
            
            # 完成
            progress.update_progress(100, "智能名称生成完成！")
            progress.close()
            
            # 显示结果
            if success_count > 0:
                messagebox.showinfo("完成", 
                                   f"成功为 {success_count}/{total_count} 个项目生成了智能名称！\n\n"
                                   "智能名称已显示在项目列表中，创建仓库时将使用这些名称。")
                self.logger.info(f"智能名称生成完成: {success_count}/{total_count}")
            else:
                messagebox.showwarning("警告", "没有成功生成任何智能名称")
                
        except Exception as e:
            if 'progress' in locals():
                progress.close()
            error_msg = f"生成智能名称时发生错误: {str(e)}"
            self.logger.error(error_msg)
            messagebox.showerror("错误", error_msg)
    
    def check_duplicate_names(self):
        """检查仓库名称是否重复"""
        if not self.projects:
            messagebox.showwarning("警告", "请先添加项目")
            return
        
        if not self.gitee_api:
            messagebox.showerror("错误", "请先配置并测试Gitee API连接")
            return
        
        # 创建检查对话框
        check_window = tk.Toplevel(self)
        check_window.title("重名检查")
        check_window.geometry("600x400")
        check_window.grab_set()
        
        # 主框架
        main_frame = ttk.Frame(check_window, padding=10)
        main_frame.pack(fill=BOTH, expand=True)
        
        # 标题
        title_label = ttk.Label(main_frame, text="仓库名称重名检查", font=("等线", 14, "bold"))
        title_label.pack(pady=(0, 10))
        
        # 结果文本框
        result_text = tk.Text(main_frame, height=20, width=70, font=("等线", 9))
        scrollbar_check = ttk.Scrollbar(main_frame, orient=VERTICAL, command=result_text.yview)
        result_text.configure(yscrollcommand=scrollbar_check.set)
        
        result_text.pack(side=LEFT, fill=BOTH, expand=True)
        scrollbar_check.pack(side=RIGHT, fill=Y)
        
        result_text.insert(END, "正在检查仓库名称...\n\n")
        check_window.update()
        
        # 检查重名
        from utils.name_translator import name_translator
        duplicate_count = 0
        
        try:
            # 获取用户的仓库列表
            success, user_repos, msg = self.gitee_api.get_user_repos(page=1, per_page=100)
            if not success:
                result_text.insert(END, f"无法获取仓库列表: {msg}\n")
                return
            
            existing_names = {repo['name'].lower() for repo in user_repos}
            
            for project in self.projects:
                original_name = project['name']
                clean_name = name_translator.clean_name(original_name)
                
                # 使用智能名称（如果有）
                if 'smart_name' in project and project['smart_name']:
                    repo_name = project['smart_name']
                else:
                    repo_name = clean_name
                
                if repo_name.lower() in existing_names:
                    result_text.insert(END, f"❌ {original_name}\n")
                    result_text.insert(END, f"   转换名称: {repo_name}\n")
                    result_text.insert(END, f"   状态: 已存在同名仓库\n\n")
                    duplicate_count += 1
                else:
                    result_text.insert(END, f"✅ {original_name}\n")
                    result_text.insert(END, f"   转换名称: {repo_name}\n")
                    result_text.insert(END, f"   状态: 可以创建\n\n")
            
            result_text.insert(END, f"检查完成！\n")
            result_text.insert(END, f"重名项目: {duplicate_count} 个\n")
            result_text.insert(END, f"可创建项目: {len(self.projects) - duplicate_count} 个\n\n")
            result_text.insert(END, f"注意: 重名项目将自动添加数字后缀。\n")
            
        except Exception as e:
            result_text.insert(END, f"检查过程中出现错误: {str(e)}\n")
        
        # 关闭按钮
        ttk_bs.Button(
            check_window,
            text="关闭",
            bootstyle=SECONDARY,
            command=check_window.destroy,
            width=15
        ).pack(pady=5)
        
        check_window.transient(self)
    
    def set_gitee_api(self, gitee_api):
        """设置Gitee API客户端"""
        self.gitee_api = gitee_api
    
    def get_projects(self) -> List[Dict[str, Any]]:
        """获取所有项目"""
        return self.projects.copy()


class ProjectEditDialog:
    """项目编辑对话框"""
    
    def __init__(self, parent, current_values):
        self.parent = parent
        self.result = None
        self.dialog = None
        # 适配新的列结构（选择、名称、路径、状态）
        self.name_var = tk.StringVar(value=current_values[1])  # 名称在第2列
        self.path_var = tk.StringVar(value=current_values[2])  # 路径在第3列
        self.create_dialog()
    
    def create_dialog(self):
        """创建对话框"""
        self.dialog = tk.Toplevel(self.parent)
        self.dialog.title("编辑项目")
        self.dialog.geometry("400x150")
        self.dialog.resizable(False, False)
        self.dialog.grab_set()
        
        # 项目名称
        ttk.Label(self.dialog, text="项目名称:").pack(pady=5)
        ttk.Entry(self.dialog, textvariable=self.name_var, width=50).pack(pady=5)
        
        # 项目路径
        ttk.Label(self.dialog, text="项目路径:").pack(pady=5)
        path_frame = ttk.Frame(self.dialog)
        path_frame.pack(pady=5)
        ttk.Entry(path_frame, textvariable=self.path_var, width=40).pack(side=LEFT)
        ttk_bs.Button(path_frame, text="浏览", command=self.browse_path).pack(side=LEFT, padx=5)
        
        # 按钮
        button_frame = ttk.Frame(self.dialog)
        button_frame.pack(pady=10)
        ttk_bs.Button(button_frame, text="确定", bootstyle=SUCCESS, command=self.ok_clicked).pack(side=LEFT, padx=5)
        ttk_bs.Button(button_frame, text="取消", bootstyle=SECONDARY, command=self.cancel_clicked).pack(side=LEFT, padx=5)
        
        # 居中显示
        self.dialog.transient(self.parent)
        self.dialog.wait_window()
    
    def browse_path(self):
        """浏览路径"""
        path = filedialog.askdirectory(title="选择项目目录")
        if path:
            self.path_var.set(path)
    
    def ok_clicked(self):
        """确定按钮点击"""
        name = self.name_var.get().strip()
        path = self.path_var.get().strip()
        
        if not name or not path:
            messagebox.showerror("错误", "项目名称和路径不能为空")
            return
        
        self.result = (name, path, "待处理")
        self.dialog.destroy()
    
    def cancel_clicked(self):
        """取消按钮点击"""
        self.dialog.destroy()


class LogTextWidget(ttk.Frame):
    """日志文本组件"""
    
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.setup_ui()
        self.logger = get_logger("LogTextWidget")
    
    def setup_ui(self):
        """设置UI"""
        # 文本框和滚动条
        self.text_widget = tk.Text(self, wrap=tk.WORD, height=10)
        scrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL, command=self.text_widget.yview)
        self.text_widget.configure(yscrollcommand=scrollbar.set)
        
        # 布局
        self.text_widget.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 配置标签样式
        self.text_widget.tag_configure("INFO", foreground="blue")
        self.text_widget.tag_configure("SUCCESS", foreground="green")
        self.text_widget.tag_configure("WARNING", foreground="orange")
        self.text_widget.tag_configure("ERROR", foreground="red")
        self.text_widget.tag_configure("DEBUG", foreground="gray")
    
    def append_log(self, message: str, level: str = "INFO"):
        """添加日志信息"""
        import datetime
        timestamp = datetime.datetime.now().strftime("%H:%M:%S")
        log_message = f"[{timestamp}] {message}\n"
        
        self.text_widget.insert(tk.END, log_message, level)
        self.text_widget.see(tk.END)
        
        # 限制行数（保留最后1000行）
        lines = self.text_widget.get("1.0", tk.END).split('\n')
        if len(lines) > 1000:
            self.text_widget.delete("1.0", f"{len(lines)-1000}.0")
    
    def clear_log(self):
        """清空日志"""
        self.text_widget.delete("1.0", tk.END)
    
    def save_log(self):
        """保存日志到文件"""
        import datetime
        from tkinter import filedialog
        
        filename = filedialog.asksaveasfilename(
            title="保存日志文件",
            defaultextension=".log",
            filetypes=[("日志文件", "*.log"), ("文本文件", "*.txt"), ("所有文件", "*.*")]
        )
        
        if filename:
            try:
                with open(filename, 'w', encoding='utf-8') as f:
                    f.write(self.text_widget.get("1.0", tk.END))
                messagebox.showinfo("成功", f"日志已保存到: {filename}")
            except Exception as e:
                messagebox.showerror("错误", f"保存日志失败: {str(e)}")


class ProgressDialog:
    """进度对话框"""
    
    def __init__(self, parent, title="处理中...", message=""):
        self.parent = parent
        self.dialog = None
        self.progress_var = tk.DoubleVar()
        self.message_var = tk.StringVar(value=message)
        self.cancelled = False
        self.create_dialog(title)
    
    def create_dialog(self, title):
        """创建对话框"""
        self.dialog = tk.Toplevel(self.parent)
        self.dialog.title(title)
        self.dialog.geometry("400x120")
        self.dialog.resizable(False, False)
        self.dialog.grab_set()
        
        # 消息标签
        self.message_label = ttk.Label(self.dialog, textvariable=self.message_var)
        self.message_label.pack(pady=10)
        
        # 进度条
        self.progress_bar = ttk_bs.Progressbar(
            self.dialog, 
            variable=self.progress_var, 
            bootstyle=INFO,
            length=300
        )
        self.progress_bar.pack(pady=10)
        
        # 取消按钮
        self.cancel_btn = ttk_bs.Button(
            self.dialog, 
            text="取消", 
            bootstyle=DANGER,
            command=self.cancel
        )
        self.cancel_btn.pack(pady=5)
        
        # 居中显示
        self.dialog.transient(self.parent)
        
        # 禁止关闭按钮
        self.dialog.protocol("WM_DELETE_WINDOW", self.cancel)
    
    def update_progress(self, value: float, message: str = ""):
        """更新进度"""
        self.progress_var.set(value)
        if message:
            self.message_var.set(message)
        self.dialog.update()
    
    def set_message(self, message: str):
        """设置消息"""
        self.message_var.set(message)
        self.dialog.update()
    
    def cancel(self):
        """取消操作"""
        self.cancelled = True
    
    def close(self):
        """关闭对话框"""
        if self.dialog:
            self.dialog.destroy()
    
    def is_cancelled(self) -> bool:
        """检查是否已取消"""
        return self.cancelled


class BatchRenameDialog:
    """批量重命名对话框"""
    
    def __init__(self, parent, selected_projects, all_projects):
        self.parent = parent
        self.selected_projects = selected_projects
        self.all_projects = all_projects
        self.result = None
        self.dialog = None
        self.rename_entries = {}  # 存储每个项目的输入框
        self.create_dialog()
    
    def create_dialog(self):
        """创建对话框"""
        import os
        
        self.dialog = tk.Toplevel(self.parent)
        self.dialog.title(f"批量调整仓库名称 ({len(self.selected_projects)} 个项目)")
        self.dialog.geometry("700x500")
        self.dialog.resizable(True, True)
        self.dialog.grab_set()
        
        # 说明文本
        info_frame = ttk.Frame(self.dialog)
        info_frame.pack(fill=X, padx=10, pady=5)
        
        info_label = ttk.Label(
            info_frame, 
            text="为选中的项目设置自定义仓库名称（仓库名称需符合Git规范：小写字母、数字、下划线、中划线）",
            font=("等线", 9),
            foreground="gray"
        )
        info_label.pack(anchor=W)
        
        # 滚动框架
        canvas_frame = ttk.Frame(self.dialog)
        canvas_frame.pack(fill=BOTH, expand=True, padx=10, pady=5)
        
        canvas = tk.Canvas(canvas_frame)
        scrollbar = ttk.Scrollbar(canvas_frame, orient=VERTICAL, command=canvas.yview)
        scrollable_frame = ttk.Frame(canvas)
        
        scrollable_frame.bind(
            "<Configure>",
            lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
        )
        
        canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        
        # 为每个选中的项目创建重命名输入框
        for i, project_path in enumerate(self.selected_projects):
            # 找到对应的项目信息
            project_info = None
            for proj in self.all_projects:
                if proj['path'] == project_path:
                    project_info = proj
                    break
            
            if not project_info:
                continue
                
            project_name = project_info['name']
            
            # 项目框架
            project_frame = ttk.LabelFrame(scrollable_frame, text=f"项目 {i+1}", padding=10)
            project_frame.pack(fill=X, pady=5)
            
            # 原始名称
            ttk.Label(project_frame, text="原始名称:", font=("等线", 9, "bold")).pack(anchor=W)
            ttk.Label(project_frame, text=project_name, foreground="gray").pack(anchor=W, pady=(0, 5))
            
            # 使用翻译器生成默认名称
            from utils.name_translator import name_translator
            default_name = name_translator.suggest_name(project_name)
            
            # 新仓库名称输入
            ttk.Label(project_frame, text="新仓库名称:", font=("等线", 9, "bold")).pack(anchor=W)
            
            input_frame = ttk.Frame(project_frame)
            input_frame.pack(fill=X, pady=(0, 5))
            
            entry_var = tk.StringVar(value=default_name)
            entry = ttk.Entry(input_frame, textvariable=entry_var, font=("等线", 10))
            entry.pack(side=LEFT, fill=X, expand=True, padx=(0, 5))
            
            
            self.rename_entries[project_path] = entry_var
            
            # 路径显示
            ttk.Label(project_frame, text="路径:", font=("等线", 8)).pack(anchor=W)
            ttk.Label(project_frame, text=project_path, font=("等线", 8), foreground="gray").pack(anchor=W)
        
        canvas.pack(side=LEFT, fill=BOTH, expand=True)
        scrollbar.pack(side=RIGHT, fill=Y)
        
        # 按钮框架
        button_frame = ttk.Frame(self.dialog)
        button_frame.pack(fill=X, padx=10, pady=10)
        
        # 批量操作按钮
        batch_frame = ttk.Frame(button_frame)
        batch_frame.pack(side=LEFT)
        
        
        ttk_bs.Button(
            batch_frame, 
            text="📝 使用原名", 
            bootstyle=INFO,
            command=self.use_original_names
        ).pack(side=LEFT, padx=(0, 5))
        
        # 主要按钮
        main_btn_frame = ttk.Frame(button_frame)
        main_btn_frame.pack(side=RIGHT)
        
        ttk_bs.Button(
            main_btn_frame, 
            text="确定", 
            bootstyle=SUCCESS,
            command=self.ok_clicked
        ).pack(side=LEFT, padx=5)
        
        ttk_bs.Button(
            main_btn_frame, 
            text="取消", 
            bootstyle=SECONDARY,
            command=self.cancel_clicked
        ).pack(side=LEFT, padx=5)
        
        # 居中显示
        self.dialog.transient(self.parent)
        self.dialog.wait_window()
    
    
    
    def use_original_names(self):
        """使用原始项目名称（经过翻译和清理）"""
        from utils.name_translator import name_translator
        
        for project_path, entry_var in self.rename_entries.items():
            project_info = None
            for proj in self.all_projects:
                if proj['path'] == project_path:
                    project_info = proj
                    break
            
            if project_info:
                clean_name = name_translator.suggest_name(project_info['name'])
                entry_var.set(clean_name)
    
    def ok_clicked(self):
        """确定按钮点击"""
        import re
        
        renamed_projects = {}
        errors = []
        
        # 验证所有输入的名称
        for project_path, entry_var in self.rename_entries.items():
            new_name = entry_var.get().strip()
            
            if not new_name:
                errors.append(f"项目路径 {project_path} 的名称不能为空")
                continue
            
            # 验证名称格式
            if not re.match(r'^[a-zA-Z0-9_-]+$', new_name):
                errors.append(f"项目名称 '{new_name}' 格式不正确，只能包含字母、数字、下划线和中划线")
                continue
            
            if len(new_name) > 100:  # Gitee限制
                errors.append(f"项目名称 '{new_name}' 过长，请控制在100字符以内")
                continue
            
            renamed_projects[project_path] = new_name
        
        if errors:
            messagebox.showerror("输入错误", "\n".join(errors))
            return
        
        # 检查是否有重复名称
        name_counts = {}
        for name in renamed_projects.values():
            name_counts[name] = name_counts.get(name, 0) + 1
        
        duplicates = [name for name, count in name_counts.items() if count > 1]
        if duplicates:
            messagebox.showwarning("重复名称", f"检测到重复的仓库名称: {', '.join(duplicates)}\n请确保每个项目的名称都是唯一的。")
            return
        
        self.result = renamed_projects
        self.dialog.destroy()
    
    def cancel_clicked(self):
        """取消按钮点击"""
        self.dialog.destroy()
